//gcc 01aes_cbc_128.c -lcrypto -o test && ./test && rm ./test
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>

//df98b715d5c6ed2b25817b6f255411a1	//HEX密钥
unsigned char key[] = {0xdf, 0x98, 0xb7, 0x15, 0xd5, 0xc6, 0xed, 0x2b, 0x25, 0x81, 0x7b, 0x6f, 0x25, 0x54, 0x11, 0xa1}; //16字节
//2841ae97419c2973296a0d4bdfe19a4f	//HEX初始向量
unsigned char stdiv[] = {0x28, 0x41, 0xae, 0x97, 0x41, 0x9c, 0x29, 0x73, 0x29, 0x6a, 0x0d, 0x4b, 0xdf, 0xe1, 0x9a, 0x4f}; //16字节

int main() {
    AES_KEY encryptkey;
    AES_KEY decryptkey;
    AES_set_encrypt_key(key,128,&encryptkey);
    AES_set_decrypt_key(key,128,&decryptkey);

    unsigned char plain_text [32]; //对齐16字节
    memcpy(plain_text, "AES encrypt in openssl demo", 27);
    memset(plain_text + 27, 0, 5); //需要将加密区块长度填充为16字节整数倍，此处使用zero-padding，即末尾全用0填充
    printf("plain_text: " ); for(int i = 0; i < 32; i++) { printf("%02X ", plain_text[i]); } printf("\n" );

    unsigned char encrypted_text [32]; //对齐16字节
    memset(encrypted_text, 0, 32);
    unsigned char tmpiv[16];
    memcpy(tmpiv, stdiv, 16);
    // AES_cbc_encrypt在加密的过程中会修改ivec(tmpiv)的内容，因此ivec参数不能是一个常量，而且不能在传递给加密函数后再立马传递给解密函数，必须重新赋值之后再传递给解密函数。
    AES_cbc_encrypt(plain_text, encrypted_text, 32, &encryptkey, tmpiv, AES_ENCRYPT);

    printf("encrypted_: " ); for(int i = 0; i < 32; i++) { printf("%02X ", encrypted_text[i]); } printf("\n" );

    unsigned char decrypted_text [32]; //对齐16字节
    memset(decrypted_text, 0, 32);
    memcpy(tmpiv, stdiv, 16);
    AES_cbc_encrypt(encrypted_text, decrypted_text, 32, &decryptkey, tmpiv, AES_DECRYPT);

    printf("decrypted_: " ); for(int i = 0; i < 32; i++) { printf("%02X ", decrypted_text[i]); } printf("\n" );
    return 0;
}
